package com.anivia.system.auth.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.anivia.common.core.constant.NumberConstant;
import com.anivia.common.core.enums.PlatformTypeEnum;
import com.anivia.common.core.util.AssertUtil;
import com.anivia.common.web.satoken.util.UserInfoUtil;
import com.anivia.system.auth.enums.ResourceBaseEnum;
import com.anivia.system.auth.enums.SwitchStatusEnum;
import com.anivia.system.auth.mapper.RoleResourceInfoMapper;
import com.anivia.system.auth.model.entity.RoleInfoDO;
import com.anivia.system.auth.model.entity.RoleResourceInfoDO;
import com.anivia.system.auth.model.entity.UserInfoDO;
import com.anivia.system.auth.model.vo.ResourceInfoVO;
import com.anivia.system.auth.service.IRoleInfoService;
import com.anivia.system.auth.service.IRoleResourceInfoService;
import com.anivia.system.auth.service.IUserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源服务实现类
 * </p>
 *
 * @author wangj
 */
@Service
public class RoleResourceInfoServiceImpl extends ServiceImpl<RoleResourceInfoMapper, RoleResourceInfoDO> implements IRoleResourceInfoService {
    @Resource
    private IUserInfoService userInfoService;
    @Resource
    private IRoleInfoService roleInfoService;

    @Override
    public List<Tree<Integer>> baseTree(PlatformTypeEnum loginType) {
        List<ResourceBaseEnum> list = ResourceBaseEnum.valuesByPlatformType(loginType);
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setParentIdKey("pid");
        List<Tree<Integer>> treeNodes = TreeUtil.<ResourceBaseEnum, Integer>build(list, NumberConstant.PID, treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getPid());
                    tree.putExtra("name", treeNode.getName());
                    tree.putExtra("weight", treeNode.getWeight());
                });
        return treeNodes;
    }

    @Override
    public List<ResourceInfoVO> resources() {
        // 查询用户的角色集合
        UserInfoDO userInfo = userInfoService.lambdaQuery()
                .eq(UserInfoDO::getId, UserInfoUtil.getLoginUserId())
                .one();
        AssertUtil.notNull(userInfo, "用户不存在");
        if (CollUtil.isEmpty(userInfo.getRoleIds())) {
            return Collections.emptyList();
        }
        // 过滤不可用的角色
        List<RoleInfoDO> list = roleInfoService.lambdaQuery()
                .in(RoleInfoDO::getId, userInfo.getRoleIds())
                .eq(RoleInfoDO::getStatus, SwitchStatusEnum.ENABLE.getCode())
                .list();
        List<Integer> newRoleIds = list.stream().map(RoleInfoDO::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(newRoleIds)) {
            return Collections.emptyList();
        }
        // 查询角色所有资源
        List<RoleResourceInfoDO> roleResourceInfoList = this.lambdaQuery()
                .in(RoleResourceInfoDO::getRoleId, newRoleIds)
                .list();
        if (CollUtil.isEmpty(roleResourceInfoList)) {
            return Collections.emptyList();
        }

        List<ResourceInfoVO> vos = roleResourceInfoList.stream().map(item -> {
            ResourceInfoVO vo = new ResourceInfoVO();
            vo.setResourceId(item.getResourceId());
            vo.setDataScope(item.getDataScope());
            vo.setCustomDeptIds(item.getCustomDeptIds());
            return vo;
        }).collect(Collectors.toList());
        return vos;
    }

    @Override
    public List<ResourceInfoVO> resources(Integer roleId) {
        // 查询角色所有资源
        List<RoleResourceInfoDO> roleResourceInfoList = this.lambdaQuery()
                .eq(RoleResourceInfoDO::getRoleId, roleId)
                .list();
        if (CollUtil.isEmpty(roleResourceInfoList)) {
            return Collections.emptyList();
        }

        List<ResourceInfoVO> vos = roleResourceInfoList.stream().map(item -> {
            ResourceInfoVO vo = new ResourceInfoVO();
            vo.setResourceId(item.getResourceId());
            vo.setDataScope(item.getDataScope());
            vo.setCustomDeptIds(item.getCustomDeptIds());
            return vo;
        }).collect(Collectors.toList());
        return vos;
    }
}
